package com.fzhucc.modules.sendDataToQz.util;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class SHA256withRSAUtil {
    private static final String RSA_CIPHER_CHARSET = "UTF-8";

    /**
     * 生成公钥，私钥
     *
     * @param keySize
     *            the size of key : 1024, 2048
     * @return Map
     */
    public static void generateKeyPair(int keySize) {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(keySize);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            byte[] publicKey = keyPair.getPublic().getEncoded();
            byte[] privateKey = keyPair.getPrivate().getEncoded();

            String publicStr = Base64.getEncoder().encodeToString(publicKey);
            System.out.println("公钥字符串----------------\n" + publicStr);
            String privateStr = Base64.getEncoder().encodeToString(privateKey);
            System.out.println("私钥字符串----------------\n" + privateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static PrivateKey genPrivateKey(String base64Rsa) {
        try {
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64Rsa));
            return kf.generatePrivate(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException("初始化秘钥异常");
        }
    }

    /**
     * 生成签名
     *
     * @param base64PriRsa openapi的私钥
     * @param inputStr 原始字符创
     * @return
     */
    public static String sign2Base64(String base64PriRsa, String inputStr) {
        try {
            PrivateKey privateKey = genPrivateKey(base64PriRsa);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(privateKey);
            signature.update(inputStr.getBytes(RSA_CIPHER_CHARSET));
            return Base64.getEncoder().encodeToString(signature.sign());
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException("rsa签名异常");
        }
    }

    /**
     * 验签名
     *
     * @param base64PubRsa    公钥
     * @param src             原始字符串
     * @param base64SignValue 原始签名
     * @return
     */
    public static boolean verifySign(String base64PubRsa, String src, String base64SignValue) {
        try {
//            System.out.println("verifySign_base64PubRsa"+base64PubRsa);
//            System.out.println("verifySign_src"+src);
//            System.out.println("verifySign_base64SignValue"+base64SignValue);
            PublicKey publicKey = genPublicKey(base64PubRsa);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(publicKey);
            signature.update(src.getBytes(RSA_CIPHER_CHARSET));
            boolean result = signature.verify(Base64.getDecoder().decode(base64SignValue));
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException("rsa验证签名异常");
        }
    }

    private static PublicKey genPublicKey(String base64Rsa) {
        try {
            KeyFactory kf = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64Rsa));
            return kf.generatePublic(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException("初始化秘钥失败");
        }
    }
}
